// (C) Copyright 2012 Kystar. All rights reserved.

`timescale 1ns/100ps
`default_nettype none

module audio_input 
(
    //--------------------------------------------------------------------
    // clocks
    //--------------------------------------------------------------------
    input  wire I_sclk,
    input  wire I_clk_25m,

    //--------------------------------------------------------------------
    // I2S
    //--------------------------------------------------------------------
    output wire mclk,
    input  wire lrck,
    input  wire sck,
    input  wire sda,

    //--------------------------------------------------------------------
    // output
    //--------------------------------------------------------------------
    output reg  [ 7: 0] O_audio_data,
    output reg          O_audio_data_valid

);

/******************************************************************************
                                <localparams>
******************************************************************************/

/******************************************************************************
                              <internal signals>
******************************************************************************/
reg  [ 1: 0] lrck_syn_dff;
reg  [ 1: 0] sck_syn_dff;
reg  [ 1: 0] sda_syn_dff;
wire lrck_syn;
wire sck_syn;
wire sda_syn;
reg  lrck_syn_dly;
reg  sck_syn_dly;
reg  [ 5: 0] cnt;
reg  [ 7: 0] audio_data;

/******************************************************************************
                                <module body>
******************************************************************************/
// mclk
//ODDR2
//#(
//    .DDR_ALIGNMENT("NONE")
//)
//u_oddr2_mclk
//(
//    .D0(1'b1),
//    .D1(1'b0),
//    .C0(I_clk_25m),
//    .C1(!I_clk_25m),
//    .CE(1),
//    .Q(mclk)
//);

assign mclk = I_clk_25m;

always @(posedge I_sclk)
    begin
    lrck_syn_dff <= {lrck_syn_dff[0],lrck};
    sck_syn_dff <= {sck_syn_dff[0],sck};
    sda_syn_dff <= {sda_syn_dff[0],sda};
    end

assign lrck_syn = lrck_syn_dff[1];
assign sck_syn = sck_syn_dff[1];
assign sda_syn = sda_syn_dff[1];

always @(posedge I_sclk)
    begin
    lrck_syn_dly <= lrck_syn;
    sck_syn_dly <= sck_syn;
    end

always @(posedge I_sclk)
    if (lrck_syn != lrck_syn_dly)
        cnt <= 'd0;
    else if (!sck_syn_dly && sck_syn)
        begin
        if (cnt != 'd32)
            cnt <= cnt + 1'b1;
        end

always @(posedge I_sclk)
    if (!sck_syn_dly && sck_syn)
        audio_data <= {audio_data[6:0],sda_syn};
    
always @(posedge I_sclk)
    if (sck_syn_dly && !sck_syn
        && (cnt == 'd9 || cnt == 'd17 || cnt == 'd25))
        O_audio_data <= audio_data;
    else if (sck_syn_dly && !sck_syn && cnt == 'd30)
        O_audio_data <= lrck_syn ? 'hAA : 'h55;

always @(posedge I_sclk)
    if (O_audio_data_valid)
        O_audio_data_valid <= 1'b0;
    else if (sck_syn_dly && !sck_syn && (cnt == 'd9 || cnt == 'd17 || cnt == 'd25))
        O_audio_data_valid <= 1'b1;
    else if (sck_syn_dly && !sck_syn && cnt == 'd30)
        O_audio_data_valid <= 1'b1;

endmodule
`default_nettype wire

